Comunicazione con Intuition: IDCMP Come abbiamo detto la puntata scorsa, la finestra rappresenta il luogo in cui il programma visualizza i dati per l'utente, ed il luogo in cui l'utente indica al programma quale operazione deve compiere; mentre le prime azioni sono svolte dalla libreria grafica e da alcune funzioni di Intuition che permettono di visualizzare testi e grafici sulla finestra, le operazioni di input su quest'utlima sono realizzate da IDCMP. IDCMP è un acronimo che significa Intuition Direct Communications Message Port, vale a dire porta messaggi per la comunicazione diretta con intuition; in altre parole intuition permette di avvissare e comunicare qualsiasi input (mouse, finestra, gadget, menù ecc.) avvenuto in una determinata finestra, all'applicazione; come avete potuto capire dal nome, IDCMP è una porta messaggi exec associata ad una finestra, che riceve un formato particolare di messaggio, IntuiMessage contenente oltre alle informazioni del messaggio exec, il tipo di evento di input, altri eventuali dati su di esso, su quale finestra è avvenuto ed altro ancora. Il programmatore deve specificare, all'atto dell'apertura della finestra, con il tag WA_IDCMP per quali messaggi deve essere avvisato mediante IDCMP; in tale maniera posso chiedere di essere semplicemente ratificato di eventi sul menù, perché devo attuare operazioni solo in risposta di questo tipo di evento; se tale campo è diverso da NULL la porta IDCMP che riceve questi messaggi di intuition, viene creata automaticamente al momento dell'apertura della finestra; se tale tag è NULL non viene aperta la porta IDCMP. Questo vuol dire che ogni finestra può avere una propria porta, ed ognuna di queste riceve i messaggi indicati all'atto dell'apertura, quando questa è attiva. E' comunque possibile modificare gli eventi per i quali essere avvisati, mediante la seguente funzione: Successo = ModifyIDCMP(Finestra,IDCMPFlags); Dove "Finestra" è il puntatore alla struttura Window della finestra; IDCMPFlags è una ULONG dello stesso tipo passato in WA_IDCMP indicante quali eventi di input gestire; Successo (utilizzato a partire da V37) se vale NULL vuol dire che non è stato possibile modificare l'IDCMP; dato che, se la precedente configurazione poteva essere NULL e modificando l'IDCMPFlags impostando almeno un evento il sistema provvede direttamente da ModifyIDCMP a creare la porta IDCMP, può accadere che non venga aperta (mancanza di memoria o altro); il puntatore alla porta creata dal sistema è presente nel campo UserPort della struttura Window. Tirando le somme, il nucleo di ogni applicazione si occupa di attendere dalla porta IDCMP messaggi di Intuition (utilizzando Wait o WaitPort come visto in una delle precedenti puntate) e di rispondere con determinate azioni quando questi arrivano; ad esempio se si seleziona l'opzione "Open" del menù, bisogna far apparire il file requester per scegliere il file da aprire; si può realizzare (vedere listati) una routine che si occupa proprio di attendere un messaggio. Come abbiamo prima accennato ogni finestra aperta può avere una propria porta IDCMP; questo non è necessario, poiché se un'applicazione apre più di una finestra, può gestire tutti i messaggi con un'unica porta, dato che nella struttura IntuiMessage vi è anche il campo per determinare da quale finestra arriva il messaggio; in altre parole la porta IDCMP viene condivisa fra più finestre; per fare questo bisogna effettuare i seguenti passi: 1 - Creare una porta messaggi exec (che sarà utilizzata come porta IDCMP) mediante CreatePort o CreateMsgPort 2 - Aprire la finestra con il tag WA_IDCMP impostato a NULL; questo impedirà ad Intuition di aprire una porta per quella finestra 3 - Inserire il puntatore della porta creata nel punto 1 nel campo UserPort della finestra appena aperta 4 - Chiamare ModifyIDCMP() per impostare i corretti IDCMPFlags per quella finestra; attenzione a non chiamare ModifyIDCMP(finestra,NULL) poiché si chiuderebbe la porta condivisa 5 - Quando l'applicazione decide di chiudere una finestra con una porta IDCMP condivisa, bisogna che vengano prima risposti tutti i messaggi, presenti nella porta, di quella finestra; esiste per questo una funzione denominata CloseWindowSafely, riportata sul ROM Kernel Manual che elimina dalla porta tutti i messaggi prima di chiudere la finestra (vedere listati); la funzione dopo aver eliminato tutti i messaggi dalla porta, assegna al campo UserPort della finestra NULL e chiama ModifyIDCMP(finestra,NULL) in modo da interrompere il flusso di messaggi senza liberare la porta (che potrebbe servire ad altre finestre) 6 - Una volta chiuse tutte le finestre, bisogna deallocare la porta mediante DeletePort (se è stata usata CreatePort) o DeleteMsgPort (se è stata usata CreateMsgPort).